<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>EventBus</title>
</head>

<body>
    <div>
        <button id="J_btn">btn1</button>
    </div>
    <script>
        const eventBus = {
            listeners: {},
            addListener: function (type, callback, scope) {
                if (typeof this.listeners[type] !== 'undefined') {
                    this.listeners[type].push({ scope: scope, callback: callback })
                } else {
                    this.listeners[type] = [
                        { scope: scope, callback: callback }
                    ]
                }
            },
            removeListener: function (type, callback, scope) {
                if (typeof this.listeners[type] !== 'undefined') {
                    const numOfCallbacks = this.listeners[type].length
                    let newArray = []
                    for (let i = 0; i < numOfCallbacks; i++) {
                        let listener = this.listeners[type][i]
                        if (listener.scope === scope && listener.callback === callback) {
                        } else {
                            newArray.push(listener)
                        }
                    }
                    this.listeners[type] = newArray
                }
            },
            removeAllListener: function () {
                this.listeners = {}
            },
            hasListener: function (type, callback, scope) {
                if (typeof this.listeners[type] !== 'undefined') {
                    const numOfCallbacks = this.listeners[type].length
                    if (callback === undefined && scope === undefined) {
                        return numOfCallbacks > 0
                    }
                    for (let i = 0; i < numOfCallbacks; i++) {
                        const listener = this.listeners[type][i]
                        if (listener.scope === scope && listener.callback === callback) {
                            return true
                        }
                    }
                }
                return false
            },
            dispatch: function (type, event, shape) {
                if (typeof this.listeners[type] !== 'undefined') {
                    const numOfCallbacks = this.listeners[type].length
                    for (let i = 0; i < numOfCallbacks; i++) {
                        let listener = this.listeners[type][i]
                        if (listener && listener.callback) {
                            listener.callback.apply(listener.scope, [event, shape])
                        }
                    }
                }
            },
        }
    </script>

    <script>
        eventBus.addListener('showModal', function(){
            alert(121212)
        })

        document.querySelector('#J_btn').addEventListener('click', function(){
            eventBus.dispatch('showModal')
        })
    </script>
</body>

</html>